package com.eian.boot.module.system.associations.role.dept.service;

import com.eian.boot.module.system.associations.role.dept.event.RoleDataScopeChangedEvent;
import com.eian.boot.module.system.associations.role.dept.mapper.RoleDeptMapper;
import com.eian.boot.module.system.associations.role.dept.model.entity.SysRoleDeptEntity;
import com.eian.boot.mybatis.core.service.BaseService;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

import static com.eian.boot.table.Tables.sys_role_dept;

/**
 * 角色部门关系管理服务（数据权限）
 * 职责：纯粹的关系数据管理，不包含业务逻辑验证
 *
 * @author alex.meng
 * @since 1.0.0
 */
@Slf4j
@Service
public class RoleDeptRelationService extends BaseService<RoleDeptMapper, SysRoleDeptEntity> {

    private final ApplicationEventPublisher eventPublisher;

    public RoleDeptRelationService(ApplicationEventPublisher eventPublisher) {
        this.eventPublisher = eventPublisher;
    }

    /**
     * 设置角色数据权限（自定义部门）
     * 先清除旧关系，再建立新关系
     *
     * @param roleId  角色ID
     * @param deptIds 部门ID列表
     */
    @Transactional(rollbackFor = Exception.class)
    public void setRoleDataScope(Long roleId, List<Long> deptIds) {
        log.debug("设置角色数据权限: roleId={}, deptIds={}", roleId, deptIds);

        // 删除原有数据权限
        this.remove(QueryWrapper.create()
                .from(sys_role_dept)
                .where(sys_role_dept.role_id.eq(roleId)));

        // 添加新的数据权限
        if (deptIds != null && !deptIds.isEmpty()) {
            List<SysRoleDeptEntity> relations = deptIds.stream()
                    .map(deptId -> SysRoleDeptEntity.builder()
                            .roleId(roleId)
                            .deptId(deptId)
                            .build())
                    .collect(Collectors.toList());
            this.saveBatch(relations);
        }

        // 发布领域事件
        eventPublisher.publishEvent(new RoleDataScopeChangedEvent(this, roleId, deptIds));
    }

    /**
     * 获取角色自定义数据权限部门ID列表
     *
     * @param roleId 角色ID
     * @return 部门ID列表
     */
    public List<Long> getDeptIdsByRoleId(Long roleId) {
        return this.queryChain()
                .select(sys_role_dept.dept_id)
                .from(sys_role_dept)
                .where(sys_role_dept.role_id.eq(roleId))
                .listAs(Long.class);
    }

    /**
     * 级联删除：当角色被删除时调用
     * 清理角色的所有部门权限关系
     *
     * @param roleId 角色ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void cascadeDeleteByRoleId(Long roleId) {
        log.debug("级联删除角色部门关系: roleId={}", roleId);

        this.remove(QueryWrapper.create()
                .from(sys_role_dept)
                .where(sys_role_dept.role_id.eq(roleId)));
    }
}

